package com.hfb.mashibing.alip8.diamondsquarealgorithm.class00;

import com.hfb.mashibing.alip8.util.ArrayUtils;

/**
 * 归并排序 (merge sort) 是一类与插入排序、交换排序、选择排序不同的另一种排序方法。
 * 归并的含义是将两个或两个以上的有序表合并成一个新的有序表。
 * 归并排序有多路归并排序、两路归并排序 , 可用于内排序，也可以用于外排序。
 * 这里仅对内排序的两路归并方法进行讨论
 *
 * 一、两路归并排序算法思路
 *
 * 分而治之(divide - conquer);每个递归过程涉及三个步骤
 * 第一, 分解: 把待排序的 n 个元素的序列分解成两个子序列, 每个子序列包括 n/2 个元素.
 * 第二, 治理: 对每个子序列分别调用归并排序MergeSort, 进行递归操作
 * 第三, 合并: 合并两个排好序的子序列,生成排序结果.
 *
 * 二、算法分析
 *
 * （1）稳定性
 *      　归并排序是一种稳定的排序。
 * （2）存储结构要求
 *     　可用顺序存储结构。也易于在链表上实现。
 * （3）时间复杂度
 *     　对长度为n的文件，需进行趟二路归并，每趟归并的时间为O(n)，故其时间复杂度无论是在最好情况下还是在最坏情况下均是O(nlgn)。
 * （4）空间复杂度
 *    　 需要一个辅助向量来暂存两有序子文件归并的结果，故其辅助空间复杂度为O(n)，显然它不是就地排序。
 *   注意：
 *     　若用单链表做存储结构，很容易给出就地的归并排序
 */
public class Code04_HalfSearch {


    public static void main(String[] args) {
        int[] array = {5, 9, 1, 9, 5, 3, 7, 6, 1};

        System.out.println("Before sort:");
        ArrayUtils.printArray(array);

        new Code01_QuickSort.QuickSort(array).sort();
        int k = halfSearchFor(array[0],array);

        System.out.println("After sort:");
        ArrayUtils.printArray(array);
    }

    /*
     *循环实现二分算法
     */
    public static int halfSearchFor(int key, int[] array) {
        int low = 0; //第一个下标
        int high = array.length - 1;//最后一个下标
        int middle = 0;
        //防越界
        if (key < array[low] || key > array[high] || low > high) {
            return -1;
        }
        while (low <= high) {
            middle = (low + high) / 2;
            if (middle == key) {
                return array[middle];
            } else if (middle < key) {
                low = middle + 1;
            } else {
                high = middle - 1;
            }
        }
        return -1;
    }

    /*
     *递归实现二分算法
     */
    public static int halfSearchRecursion(int key,int[] array,int low,int high){
        //防越界
        if (key < array[low] || key > array[high] || low > high) {
            return -1;
        }
        int middle = (low+high)/2;
        if(array[middle]>key){
            //大于关键字
            return  halfSearchRecursion(key,array,low,middle-1);
        }else if(array[middle]<key){
            //小于关键字
            return halfSearchRecursion(key,array,middle+1,high);
        }else{
            return array[middle];
        }
    }

}
